package top.ochiamalu.aioj.controller;

import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.ochiamalu.aioj.common.BaseResponse;
import top.ochiamalu.aioj.common.ErrorCode;
import top.ochiamalu.aioj.converter.UserConverters;
import top.ochiamalu.aioj.domain.dto.user.AddEmailDTO;
import top.ochiamalu.aioj.domain.dto.user.UpdatePhoneDTO;
import top.ochiamalu.aioj.domain.dto.user.UpdatePasswordDTO;
import top.ochiamalu.aioj.domain.dto.user.UpdateUserDetailDTO;
import top.ochiamalu.aioj.domain.dto.user.UserLoginDTO;
import top.ochiamalu.aioj.domain.dto.user.UserRegistrationDTO;
import top.ochiamalu.aioj.domain.entity.User;
import top.ochiamalu.aioj.domain.vo.profile.UserSecureInfoVO;
import top.ochiamalu.aioj.domain.vo.user.UpdateUserDetailVO;
import top.ochiamalu.aioj.domain.vo.user.UserInfoVO;
import top.ochiamalu.aioj.domain.vo.user.UserLoginVO;
import top.ochiamalu.aioj.domain.vo.user.UserVO;
import top.ochiamalu.aioj.exception.BusinessException;
import top.ochiamalu.aioj.service.UserService;
import top.ochiamalu.aioj.util.IPUtils;
import top.ochiamalu.aioj.util.ResultUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 用户控制器
 *
 * @author OchiaMalu
 * @date 2024/12/08
 */
@RestController
@RequestMapping("/users")
@Slf4j
public class UserController {

    @Resource
    private UserService userService;

    /**
     * 用户注册
     *
     * @param userRegistrationDTO 用户注册数据
     * @return {@link BaseResponse }<{@link UserLoginVO }>
     */
    @PostMapping("/register")
    public BaseResponse<UserLoginVO> register(@RequestBody UserRegistrationDTO userRegistrationDTO, HttpServletRequest request) {
        log.info("Received registration request for account: {}", userRegistrationDTO.getAccount());
        if (StringUtils.isAnyBlank(userRegistrationDTO.getAccount(), userRegistrationDTO.getPassword(),
                userRegistrationDTO.getEmail())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请输入正确的信息");
        }
        String address = IPUtils.getUserIpAddress(request);
        userRegistrationDTO.setAddress(address);
        UserLoginVO loginVO = userService.register(userRegistrationDTO);
        log.info("Registration result for account {}: {}", userRegistrationDTO.getAccount(), true);
        return ResultUtils.success(loginVO);
    }

    /**
     * 用户登录
     *
     * @param userLoginDTO 用户登录dto
     * @return {@link BaseResponse }<{@link UserLoginVO }>
     */
    @PostMapping("/login")
    public BaseResponse<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO, HttpServletRequest request) {
        log.info("Received login request for account: {}", userLoginDTO.getAccount());
        if (StringUtils.isAnyBlank(userLoginDTO.getAccount(), userLoginDTO.getPassword())) {
            log.error("Login failed due to invalid parameters for account: {}", userLoginDTO.getAccount());
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请输入正确的账户和密码");
        }
        String address = IPUtils.getUserIpAddress(request);
        userLoginDTO.setAddress(address);
        UserLoginVO user = userService.login(userLoginDTO);
        log.info("Login successful for account: {}", userLoginDTO.getAccount());
        return ResultUtils.success(user);
    }

    /**
     * 检查登录
     *
     * @return {@link BaseResponse }<{@link Boolean }>
     */
    @GetMapping("/check")
    public BaseResponse<Boolean> checkLogin() {
        return ResultUtils.success(StpUtil.isLogin());
    }

    /**
     * 获取登录用户信息
     *
     * @return {@link BaseResponse }<{@link UserVO }>
     */
    @GetMapping
    public BaseResponse<UserVO> getUserInfo() {
        Object userId = StpUtil.getLoginIdDefaultNull();
        if (userId == null) {
            log.error("Attempted to get user info without login");
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        User user = userService.getById(Long.parseLong(userId.toString()));
        UserVO userVO = UserConverters.INSTANCE.convertEntity2VO(user);
        log.info("User info retrieved successfully for user ID: {}", userId);
        return ResultUtils.success(userVO);
    }

    /**
     * 用户登出
     *
     * @return {@link BaseResponse }<{@link Boolean }>
     */
    @PostMapping("/logout")
    public BaseResponse<Boolean> logout() {
        try {
            StpUtil.logout();
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "系统内部错误");
        }
        return ResultUtils.success(true);
    }

    /**
     * 更新用户信息
     *
     * @param updateUserDetailDTO 更新用户详细信息dto
     * @return {@link BaseResponse }<{@link Boolean }>
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateUserInfo(@RequestBody UpdateUserDetailDTO updateUserDetailDTO) {
        if (updateUserDetailDTO.getUserId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = userService.updateUserDetail(updateUserDetailDTO);
        return ResultUtils.success(result);
    }

    /**
     * 获取用户详细信息
     *
     * @return {@link BaseResponse }<{@link UpdateUserDetailVO }>
     */
    @GetMapping("/detail")
    public BaseResponse<UpdateUserDetailVO> getUserDetail() {
        UpdateUserDetailVO userVO = userService.getUserDetail();
        return ResultUtils.success(userVO);
    }

    /**
     * 按用户名获取用户信息
     *
     * @param account 账户
     * @return {@link BaseResponse }<{@link UserInfoVO }>
     */
    @GetMapping("/{account}")
    public BaseResponse<UserInfoVO> getUserInfoByUsername(@PathVariable("account") String account) {
        if (StringUtils.isBlank(account)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        UserInfoVO userInfoVO = userService.getUserInfo(account);
        return ResultUtils.success(userInfoVO);
    }

    /**
     * 获取用户安全信息
     *
     * @return {@link BaseResponse }<{@link UserSecureInfoVO }>
     */
    @GetMapping("/secure")
    public BaseResponse<UserSecureInfoVO> getUserSecureInfo() {
        UserSecureInfoVO userSecureInfoVO = userService.getUserSecureInfo();
        return ResultUtils.success(userSecureInfoVO);
    }

    /**
     * 添加电子邮件
     *
     * @param addEmailDTO 添加电子邮件dto
     * @return {@link BaseResponse }<{@link Boolean }>
     */
    @PostMapping("/addEmail")
    public BaseResponse<Boolean> addEmail(@RequestBody AddEmailDTO addEmailDTO) {
        if (StringUtils.isBlank(addEmailDTO.getEmail())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = userService.addEmail(addEmailDTO.getEmail());
        return ResultUtils.success(result);
    }


    @PostMapping("/update/phone")
    public BaseResponse<Boolean> modifyPhone(@RequestBody UpdatePhoneDTO updatePhoneDTO) {
        if (StringUtils.isBlank(updatePhoneDTO.getPhone())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = userService.modifyPhone(updatePhoneDTO.getType(), updatePhoneDTO.getPhone(), updatePhoneDTO.getCode());
        return ResultUtils.success(result);
    }

    @PostMapping("/update/password")
    public BaseResponse<Boolean> updatePassword(@RequestBody UpdatePasswordDTO updatePasswordDTO) {
        if (StringUtils.isBlank(updatePasswordDTO.getOldPassword()) || StringUtils.isBlank(updatePasswordDTO.getNewPassword())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = userService.updatePassword(updatePasswordDTO.getOldPassword(), updatePasswordDTO.getNewPassword());
        return ResultUtils.success(result);
    }
}
